package com.privatework.common.service.hostel.impl;

import com.privatework.common.QueryConditionVo;
import com.privatework.common.constants.SystemConstant;
import com.privatework.common.converter.ClassRoomConverter;
import com.privatework.common.converter.ClassRoomUseHistoryConverter;
import com.privatework.common.converter.HostelInfoConverter;
import com.privatework.common.entity.classroom.ClassRoom;
import com.privatework.common.entity.classroom.ClassRoomUseHistory;
import com.privatework.common.entity.classroom.QClassRoom;
import com.privatework.common.entity.classroom.QClassRoomUseHistory;
import com.privatework.common.entity.hostel.HostelInfo;
import com.privatework.common.entity.hostel.QHostelInfo;
import com.privatework.common.entity.user.UserEntity;
import com.privatework.common.repository.classroom.ClassRoomRepository;
import com.privatework.common.repository.classroom.ClassRoomUseHistoryRepository;
import com.privatework.common.repository.hostel.HostelInfoRepository;
import com.privatework.common.repository.leave.LeaveInfoRepository;
import com.privatework.common.repository.user.UserRepository;
import com.privatework.common.requestvo.classroom.ClassRoomReqVo;
import com.privatework.common.requestvo.hostel.HostelInfoReqVo;
import com.privatework.common.service.classroom.ClassRoomService;
import com.privatework.common.service.hostel.HostelInfoService;
import com.privatework.common.utils.DateUtils;
import com.privatework.common.vo.classroom.ClassRoomHistoryResultVo;
import com.privatework.common.vo.classroom.ClassRoomResultVo;
import com.privatework.common.vo.hostel.HostelInfoResultVo;
import com.querydsl.core.QueryResults;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author johnny
 * @create 2021-04-12 3:05 下午
 **/
@Service
@Slf4j
public class HostelInfoServiceImpl implements HostelInfoService {

    @Autowired
    private JPAQueryFactory queryFactory;

    @Autowired
    private HostelInfoRepository hostelInfoRepository;

    @Autowired
    private UserRepository userRepository;


    @Override
    public Page<HostelInfoResultVo> listByCondition(Long userId, Pageable pageable) {
        UserEntity userEntity = userRepository.findById(userId).orElse(null);
        Long hostelId = null;
        if (userEntity != null) {
            hostelId = userEntity.getHostelId();
        }
        List<HostelInfoResultVo> hostelInfoResultVos = new ArrayList<>();
        QHostelInfo qHostelInfo = QHostelInfo.hostelInfo;
        QueryResults<HostelInfo> queryResults;
        if (hostelId != null && hostelId != 0) {
            JPAQuery<HostelInfo> jpaQuery = queryFactory.selectFrom(qHostelInfo)
                    .offset(pageable.getPageNumber() * (pageable.getPageSize() - 1))
                    .limit(pageable.getPageSize() - 1);

            HostelInfo currentHostelInfo = hostelInfoRepository.findById(hostelId).orElse(null);

            HostelInfoResultVo currentHostelInfoResultVo = HostelInfoConverter.INSTANCE.domain2vo(currentHostelInfo);

            if (currentHostelInfoResultVo.getCount() != null && currentHostelInfoResultVo.getCount() < 6) {
                currentHostelInfoResultVo.setStatus("有空位");
            } else {
                currentHostelInfoResultVo.setStatus("已满员");
            }
            currentHostelInfoResultVo.setCurrentHostel("当前宿舍");
            hostelInfoResultVos.add(currentHostelInfoResultVo);

            jpaQuery.where(qHostelInfo.id.ne(hostelId));
            queryResults = jpaQuery.fetchResults();
            queryResults.getResults().forEach(hostelInfo -> {
                HostelInfoResultVo hostelInfoResultVo = HostelInfoConverter.INSTANCE.domain2vo(hostelInfo);
                if (hostelInfoResultVo.getCount() < 6) {
                    hostelInfoResultVo.setStatus("有空位");
                } else {
                    hostelInfoResultVo.setStatus("已满员");
                }
                hostelInfoResultVos.add(hostelInfoResultVo);
            });
        } else {
            JPAQuery<HostelInfo> jpaQuery = queryFactory.selectFrom(qHostelInfo)
                    .offset(pageable.getPageNumber() * (pageable.getPageSize()))
                    .limit(pageable.getPageSize());
            queryResults = jpaQuery.fetchResults();
            queryResults.getResults().forEach(hostelInfo -> {
                HostelInfoResultVo hostelInfoResultVo = HostelInfoConverter.INSTANCE.domain2vo(hostelInfo);
                if (hostelInfoResultVo.getCount() < 6) {
                    hostelInfoResultVo.setStatus("有空位");
                } else {
                    hostelInfoResultVo.setStatus("已满员");
                }
                hostelInfoResultVos.add(hostelInfoResultVo);
            });
        }
        return new PageImpl<>(hostelInfoResultVos, pageable, queryResults.getTotal());
    }

    @Override
    public void submitHostelInfoEdit(HostelInfoReqVo hostelInfoReqVo) {
        if (hostelInfoReqVo.getUserId() != null) {

            HostelInfo hostelInfo = hostelInfoRepository.findById(hostelInfoReqVo.getId()).orElse(null);
            if (hostelInfo != null) {
                if (hostelInfo.getCount() == 6) {
                    return;
                }
            }
            Long userId = hostelInfoReqVo.getUserId();
            UserEntity userEntity = userRepository.findById(userId).orElse(null);
            if (userEntity != null ) {
                if (userEntity.getHostelId() != null) {
                    HostelInfo oldHostelInfo = hostelInfoRepository.findById(userEntity.getHostelId()).orElse(null);
                    if (oldHostelInfo != null) {
                        if (oldHostelInfo.getCount() < 6) {
                            oldHostelInfo.setCount(oldHostelInfo.getCount() + 1);
                        }
                        hostelInfoRepository.save(oldHostelInfo);
                    }
                } else {
                    HostelInfo newHostelInfo = hostelInfoRepository.findById(hostelInfoReqVo.getId()).orElse(null);
                    if (newHostelInfo != null) {
                        if (newHostelInfo.getCount() != null) {
                            if (newHostelInfo.getCount() >= 0) {
                                newHostelInfo.setCount(newHostelInfo.getCount() + 1);
                            }
                        }
                        hostelInfoRepository.save(newHostelInfo);
                    }
                    userEntity.setHostelId(hostelInfoReqVo.getId());
                    userRepository.save(userEntity);
                }


                if (hostelInfo != null) {
                    hostelInfo.setCount(hostelInfo.getCount() + 1);
                    hostelInfoRepository.save(hostelInfo);
                }

            }
        }
    }

    @Override
    public HostelInfoResultVo findHostelInfo(Long userId) {
        UserEntity userEntity = userRepository.findById(userId).orElse(null);
        if (userEntity != null) {
            Long hostelId = userEntity.getHostelId();
            if (hostelId != null) {
                HostelInfo hostelInfo = hostelInfoRepository.findById(hostelId).orElse(null);
                if (hostelInfo != null) {
                    return HostelInfoConverter.INSTANCE.domain2vo(hostelInfo);
                }
            }
        }
        return null;
    }

    @Override
    public void fillCondition(JPAQuery<HostelInfo> jpaQuery, QueryConditionVo queryConditionVo) {
        QClassRoom qClassRoom = QClassRoom.classRoom;
        ClassRoomReqVo classRoomReqVo = (ClassRoomReqVo) queryConditionVo;
        if (StringUtils.isNotEmpty(classRoomReqVo.getCode())) {
            jpaQuery.where(qClassRoom.code.like("%" + classRoomReqVo.getCode() + "%"));
        }
    }
}